package com.xuantian.baoming.controller;


import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.wechat.pay.contrib.apache.httpclient.auth.Verifier;
import com.wechat.pay.java.core.Config;
import com.wechat.pay.java.core.RSAAutoCertificateConfig;
import com.wechat.pay.java.service.payments.jsapi.JsapiServiceExtension;
import com.wechat.pay.java.service.payments.jsapi.model.PrepayRequest;
import com.wechat.pay.java.service.payments.jsapi.model.PrepayWithRequestPaymentResponse;
import com.xuantian.baoming.config.wxPayConfig;
import com.xuantian.baoming.entity.OrderInfo;
import com.xuantian.baoming.mapper.OrderInfoMapper;
import com.xuantian.baoming.service.WxJsapiService;
import com.xuantian.baoming.service.WxPayService;
import com.xuantian.baoming.util.HttpUtils;
import com.xuantian.baoming.util.UserAgentUtil;
import com.xuantian.baoming.util.WechatPay2ValidatorForRequest;
import com.xuantian.baoming.vo.R;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;

@CrossOrigin //开放前端的跨域访问
@RestController
@RequestMapping("/api/wx-jsapi")
@Slf4j
public class WxJsapiController {

    @Autowired
    private WxJsapiService wxJsapiService;
    @Autowired
    private Verifier verifier;
    @Autowired
    private WxPayService wxPayService;
    @Autowired
    wxPayConfig wxPayConfig;

    /**
     * jsapi下单
     * @param
     * @throws Exception
     */
    @PostMapping("/jsapi")
    private R<Map<String,Object>> jsapiPay(String code,@RequestBody OrderInfo orderInfo1)  {

        log.info("code-------："+code);
        log.info("用户信息："+orderInfo1.toString());

        //String openId = "11";
        if (code ==null){
            return R.fail(500,"请使用微信扫码,并授权后重试！");
        }

        log.info("发起支付请求");
        R<Map<String, Object>> mapR = wxJsapiService.jsapiPay(code, orderInfo1);

        return mapR;
    }
    //获取签名
    public String getPaySign(){
        JsapiServiceExtension service = new JsapiServiceExtension.Builder().config(wxPayConfig.getConfig()).build();
        // 跟之前下单示例一样，填充预下单参数
        PrepayRequest request = new PrepayRequest();
        request.setAppid(wxPayConfig.getAppid());
        request.setMchid(wxPayConfig.getMchId());
//        request.setAmount(1);
        // response包含了调起支付所需的所有参数，可直接用于前端调起支付
        PrepayWithRequestPaymentResponse response = service.prepayWithRequestPayment(request);
        return response.getPaySign();
    }

    /**
     * 支付通知
     * 微信支付通过支付通知接口将用户支付成功消息通知给商户
     */
    @PostMapping("/jsapi/notify")
    public String jsapiNotify(HttpServletRequest request, HttpServletResponse response){

        Gson gson = new Gson();
        Map<String, String> map = new HashMap<>();//应答对象

        try {

            //处理通知参数
            String body = HttpUtils.readData(request);
            Map<String, Object> bodyMap = gson.fromJson(body, HashMap.class);
            String requestId = (String)bodyMap.get("id");
            log.info("支付通知的id ===> {}", requestId);
            log.info("支付通知的完整数据 ===> {}", body);
            //int a = 9 / 0;

            //签名的验证
            WechatPay2ValidatorForRequest wechatPay2ValidatorForRequest
                    = new WechatPay2ValidatorForRequest(verifier, requestId, body);
            if(!wechatPay2ValidatorForRequest.validate(request)){

                log.error("通知验签失败");
                //失败应答
                response.setStatus(500);
                map.put("code", "ERROR");
                map.put("message", "通知验签失败");
                return gson.toJson(map);
            }
            log.info("通知验签成功");

            //处理订单
            wxPayService.processOrder(bodyMap);

//            //应答超时
//            //模拟接收微信端的重复通知
//            TimeUnit.SECONDS.sleep(5);

            //成功应答
            response.setStatus(200);
            map.put("code", "SUCCESS");
            map.put("message", "成功");
            return gson.toJson(map);

        } catch (Exception e) {
            e.printStackTrace();
            //失败应答
            response.setStatus(500);
            map.put("code", "ERROR");
            map.put("message", "失败");
            return gson.toJson(map);
        }

    }

}